﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Besiege
{
    public partial class Form1 : Form
    {
        Random rand = new Random();
        /// <summary>
        /// 破城概率
        /// </summary>
        private int defChance = -99;
        /// <summary>
        /// 默认周期天数
        /// </summary>
        private int defPhase = 30;
        /// <summary>
        /// 是否围城中
        /// </summary>
        private bool sieging = false;

        private int status = 0;
        private int leader = 0;
        private int artillery = 0;
        private int blockade = 0;
        private int fort = 0;
        private int wall = 0;
        private int dice = 0;
        private int phases = 0;
        private int days = 0;
        private int curStatus = 0;
        private double chance = -99;

        /// <summary>
        /// 驻军数量
        /// </summary>
        private int garrison = 1000;

        /// <summary>
        /// 实际周期天数
        /// </summary>
        private int phase = 30;
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 更新修正值显示
        /// </summary>
        private void SetModifications()
        {
            lblStatus.Text = status.ToString();
            lblLeader.Text = leader.ToString();
            lblArt.Text = artillery.ToString();
            lblBlock.Text = blockade.ToString();
            lblFort.Text = fort.ToString();
            lblWall.Text = wall.ToString();
            lblDice.Text = dice.ToString();
            lblChance.Text = $"{chance}%";
            lblPhase.Text = phases.ToString();
            lblDay.Text = days.ToString();
            lblGarrison.Text = garrison.ToString();
            lblCurStatus.Text = Data.siegeStatus[curStatus].desc;
        }
        /// <summary>
        /// 开始围城 - 锁定设置项
        /// </summary>
        private void StartSiege()
        {
            //锁定
            chkUnblocked.Enabled = false;
            numFortlev.Enabled = false;
            numDef.Enabled = false;
            numArt.Enabled = false;
            numLeader.Enabled = false;
            numSiege.Enabled = false;
            //初始化状态
            garrison = (int)numFortlev.Value * 1000;
            status = 0;
            leader = (int)numLeader.Value;
                //炮兵修正 = 炮兵 / (要塞Lev + 1)
            artillery = (int)(numArt.Value / (numFortlev.Value + 1));
            if (artillery > 5) //最大炮兵加成为+5
                artillery = 5;
                //沿海未封锁-2
            blockade = chkUnblocked.Checked ? -2 : 0;
            fort = 0 - (int)numFortlev.Value;
            wall = 0;
            dice = 0;
                //周期长度 = 30 * (攻城能力-要塞防御)
            phase = (int)(30 * (1-0.01*(int)(numSiege.Value - numDef.Value)));
            SetModifications();
            //开始围城
            sieging = true;
        }
        /// <summary>
        /// 停止围城 - 激活所有设置项并重置进度
        /// </summary>
        private void StopSiege()
        {
            //激活
            chkUnblocked.Enabled = true;
            numFortlev.Enabled = true;
            numDef.Enabled = true;
            numArt.Enabled = true;
            numLeader.Enabled = true;
            numSiege.Enabled = true;
            //重置
            garrison = (int)numFortlev.Value * 1000;
            status = 0;
            leader = 0;
            artillery = 0;
            blockade = 0;
            fort = 0;
            wall = 0;
            dice = 0;
            phases = 0;
            days = 0;
            curStatus = 0;
            chance = defChance;
            SetModifications();

            phase = defPhase;
            //结束围城
            sieging = false;
            btnNext.Enabled = true;
        }

        /// <summary>
        /// 下一轮
        /// </summary>
        private void Next()
        {
            days += phase;
            phases++;
            dice = rand.Next(0, 14) + 1;
            //骰子点数 +（炮兵加成 + 过时堡垒加成）/ 3 + 进攻方最大堡垒加成 / 10 > 14 则城墙破裂
            int wallbreak = dice + artillery / 3 + (-1) * fort / 10;
            if (wallbreak > 14) 
            {
                //城墙破裂
                if (wall < 3)
                    wall++;
            }
            int result = status + leader + blockade 
                + fort + wall + dice;
            if (result >= 5 && result <= 11)
                curStatus = 1;
            else if (result >= 12 && result <= 13)
                curStatus = 2;
            else if (result >= 14 && result <= 15)
                curStatus = 3;
            else if (result >= 16 && result <= 19)
                curStatus = 4;
            else if (result >= 20)
            {
                curStatus = 5;
                Surrender();
            }
            else
                curStatus = 0;
            garrison = (int)(garrison*(1 - Data.siegeStatus[curStatus].loss));
            //守军全灭自动投降
            if (garrison <= 0)
            {
                garrison = 0;
                Surrender();
            }
            status += curStatus;
            if (btnNext.Enabled == true)
                chance = GetChance(status + leader + blockade
                    + fort + wall);
            else
                chance = 100;
            SetModifications();
        }
        /// <summary>
        /// 攻克
        /// </summary>
        private void Surrender()
        {
            MessageBox.Show($"攻克要塞！围城共持续了{days}天！");
            btnNext.Enabled = false;
        }

        /// <summary>
        /// 使用表格伪计算攻克几率
        /// </summary>
        /// <param name="bonus"></param>
        /// <returns></returns>
        private int GetChance(int bonus)
        {
            return 7 * (bonus - 5);
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            StopSiege();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            if (!sieging)
            {
                StartSiege();
            }
            Next();
        }

        private void numFortlev_ValueChanged(object sender, EventArgs e)
        {
            lblGarrison.Text = (numFortlev.Value * 1000).ToString();
        }
    }
}
